{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Created by william from lexueoude.com.\n",
    "更多正版技术视频讲解，\n",
    "公众号 1.乐学偶得（lexueoude）\n",
    "2.乐学FinTech (LoveShareFinTech)\n",
    "\n",
    "\n",
    "1.金融市场两方：\n",
    "\n",
    "买方 （Buy-side 一级市场、二级市场，组合策略思想）\n",
    "卖方 （Sell-side 做撮合，产品销售，产品设计（金融衍生品））\n",
    "\n",
    "2.量化的两派：\n",
    "\n",
    "P-Quant(真实概率) 买方\n",
    "**注意：你所认为的\"滑点\"，不一定是真的。注意你的对手方，获取行情tick级的与下单等操作的时间\n",
    "\n",
    "Q-Quant(风险中性) 卖方\n",
    "\n",
    "推荐网站：http://gouthamanbalaraman.com/\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# 导入常用库\n",
    "import QuantLib as ql\n",
    "import pandas as pd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "January 30th, 2022\n"
     ]
    }
   ],
   "source": [
    "# 时间相关操作，用的是Date构造器\n",
    "\n",
    "date = ql.Date(30,1,2022)\n",
    "\n",
    "print(date)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "2022"
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 反向获取date对象中的信息\n",
    "\n",
    "date.year()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "1"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "date.month()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "30"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "date.dayOfMonth()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "True"
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "date.weekday() == ql.Sunday"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "Date(1,2,2022)"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 先测试一下\n",
    "date+2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "data": {
      "text/plain": "QuantLib.QuantLib.Date"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 看数据类型\n",
    "\n",
    "type(date+1)\n",
    "\n",
    "# type(1)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "买入【乐学偶得】的第一天：January 30th, 2022\n",
      "买入【乐学偶得】的后一天：January 31st, 2022\n",
      "买入【乐学偶得】的第三天：February 1st, 2022\n",
      "买入【乐学偶得】的后一周：February 6th, 2022\n",
      "买入【乐学偶得】的后两周：February 13th, 2022\n",
      "买入【乐学偶得】的后一个月：February 28th, 2022\n",
      "买入【乐学偶得】的后一个月：March 30th, 2022\n",
      "买入【乐学偶得】的后一个月：April 30th, 2022\n",
      "买入【乐学偶得】的后一个月：May 30th, 2022\n",
      "买入【乐学偶得】的后一个月：June 30th, 2022\n",
      "买入【乐学偶得】的后一个月：July 30th, 2022\n",
      "买入【乐学偶得】的后一个年：January 30th, 2023\n",
      "买入【乐学偶得】的第二年年：January 30th, 2024\n",
      "买入【乐学偶得】的第三年：January 30th, 2025\n"
     ]
    }
   ],
   "source": [
    "print(\"买入【乐学偶得】的第一天：{0}\".format(date))\n",
    "print(\"买入【乐学偶得】的后一天：{0}\".format(date+1))\n",
    "print(\"买入【乐学偶得】的第三天：{0}\".format(date+2))\n",
    "print(\"买入【乐学偶得】的后一周：{0}\".format(date+ql.Period(1,ql.Weeks)))\n",
    "print(\"买入【乐学偶得】的后两周：{0}\".format(date+ql.Period(2,ql.Weeks)))\n",
    "\n",
    "# 恶魔在细节之中，注意时间并不是标准的30天（二月份）\n",
    "print(\"买入【乐学偶得】的后一个月：{0}\".format(date+ql.Period(1,ql.Months)))\n",
    "print(\"买入【乐学偶得】的后一个月：{0}\".format(date+ql.Period(2,ql.Months)))\n",
    "print(\"买入【乐学偶得】的后一个月：{0}\".format(date+ql.Period(3,ql.Months)))\n",
    "print(\"买入【乐学偶得】的后一个月：{0}\".format(date+ql.Period(4,ql.Months)))\n",
    "print(\"买入【乐学偶得】的后一个月：{0}\".format(date+ql.Period(5,ql.Months)))\n",
    "print(\"买入【乐学偶得】的后一个月：{0}\".format(date+ql.Period(6,ql.Months)))\n",
    "\n",
    "\n",
    "\n",
    "print(\"买入【乐学偶得】的后一个年：{0}\".format(date+ql.Period(1,ql.Years)))\n",
    "print(\"买入【乐学偶得】的第二年年：{0}\".format(date+ql.Period(2,ql.Years)))\n",
    "print(\"买入【乐学偶得】的第三年：{0}\".format(date+ql.Period(3,ql.Years)))\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "按照纯天数计算,收购完成日为：March 1st, 2022\n",
      "按照中国的工作日计算,收购完成日为：March 11th, 2022\n",
      "按照美国的工作日计算,收购完成日为：March 14th, 2022\n",
      "按照英国的工作日计算,收购完成日为：March 11th, 2022\n",
      "按照日本的工作日计算,收购完成日为：March 15th, 2022\n"
     ]
    }
   ],
   "source": [
    "# 注意！！！不是每天都在交易的\n",
    "# 通过筛选每个国家的节假日，剩下的交易日（工作日）进行策略编写、产品建模等等\n",
    "# 分国别获取特定的日历\n",
    "\n",
    "\n",
    "China_calendar = ql.China()\n",
    "US_calendar = ql.UnitedStates()\n",
    "UK_calendar = ql.UnitedKingdom()\n",
    "Japan_calendar = ql.Japan()\n",
    "\n",
    "# 实际情况：乐学偶得收购（M&A）William Inc.将在30个工作日(交易日)后完成\n",
    "\n",
    "# 如果是按照raw date进行计算（直接加30天）\n",
    "period = ql.Period(30,ql.Days)\n",
    "raw_date = date + period\n",
    "\n",
    "China_date = China_calendar.advance(date, period)\n",
    "US_date = US_calendar.advance(date, period)\n",
    "UK_date = UK_calendar.advance(date, period)\n",
    "Japan_date = Japan_calendar.advance(date, period)\n",
    "\n",
    "\n",
    "print(\"按照纯天数计算,收购完成日为：{0}\".format(raw_date))\n",
    "\n",
    "print(\"按照中国的工作日计算,收购完成日为：{0}\".format(China_date))\n",
    "print(\"按照美国的工作日计算,收购完成日为：{0}\".format(US_date))\n",
    "print(\"按照英国的工作日计算,收购完成日为：{0}\".format(UK_date))\n",
    "print(\"按照日本的工作日计算,收购完成日为：{0}\".format(Japan_date))\n",
    "\n",
    "# 注意！！！不一定完全准确，需要定期人为干预"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "# 更多的细节操作：https://quantlib-python-docs.readthedocs.io/en/latest/index.html"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Is Business Day :  True\n",
      "Is Business Day :  False\n",
      "Is Business Day :  False\n",
      "Is Business Day :  True\n"
     ]
    }
   ],
   "source": [
    "# 自定义节假日\n",
    "cal = ql.TARGET()\n",
    "\n",
    "day1 = ql.Date(26, 2, 2020)\n",
    "day2 = ql.Date(10, 4, 2020)\n",
    "\n",
    "print('Is Business Day : ', cal.isBusinessDay(day1))\n",
    "print('Is Business Day : ', cal.isBusinessDay(day2))\n",
    "\n",
    "cal.addHoliday(day1)\n",
    "cal.removeHoliday(day2)\n",
    "\n",
    "print('Is Business Day : ', cal.isBusinessDay(day1))\n",
    "print('Is Business Day : ', cal.isBusinessDay(day2))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Is Business Day :  True\n",
      "Is Business Day :  False\n"
     ]
    }
   ],
   "source": [
    "China_calendar_02 = ql.China()\n",
    "\n",
    "someday_in_china_calendar = ql.Date(26, 1, 2022)\n",
    "print('Is Business Day : ', China_calendar_02.isBusinessDay(someday_in_china_calendar))\n",
    "\n",
    "# 假设这天因为新的节假日安排，这天休息\n",
    "China_calendar_02.addHoliday(someday_in_china_calendar)\n",
    "print('Is Business Day : ', China_calendar_02.isBusinessDay(someday_in_china_calendar))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "data": {
      "text/plain": "           乐学偶得-现金流发生日期\n0     January 2nd, 2020\n1    February 3rd, 2020\n2       March 2nd, 2020\n3       April 1st, 2020\n4         May 6th, 2020\n5        June 1st, 2020\n6        July 1st, 2020\n7      August 3rd, 2020\n8   September 1st, 2020\n9     October 9th, 2020\n10   November 2nd, 2020\n11   December 1st, 2020\n12    January 4th, 2021\n13   February 1st, 2021\n14      March 1st, 2021\n15      April 1st, 2021\n16        May 3rd, 2021\n17       June 1st, 2021\n18       July 1st, 2021\n19     August 2nd, 2021\n20  September 1st, 2021\n21    October 1st, 2021\n22   November 1st, 2021\n23   December 1st, 2021\n24    January 3rd, 2022",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>乐学偶得-现金流发生日期</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>0</td>\n      <td>January 2nd, 2020</td>\n    </tr>\n    <tr>\n      <td>1</td>\n      <td>February 3rd, 2020</td>\n    </tr>\n    <tr>\n      <td>2</td>\n      <td>March 2nd, 2020</td>\n    </tr>\n    <tr>\n      <td>3</td>\n      <td>April 1st, 2020</td>\n    </tr>\n    <tr>\n      <td>4</td>\n      <td>May 6th, 2020</td>\n    </tr>\n    <tr>\n      <td>5</td>\n      <td>June 1st, 2020</td>\n    </tr>\n    <tr>\n      <td>6</td>\n      <td>July 1st, 2020</td>\n    </tr>\n    <tr>\n      <td>7</td>\n      <td>August 3rd, 2020</td>\n    </tr>\n    <tr>\n      <td>8</td>\n      <td>September 1st, 2020</td>\n    </tr>\n    <tr>\n      <td>9</td>\n      <td>October 9th, 2020</td>\n    </tr>\n    <tr>\n      <td>10</td>\n      <td>November 2nd, 2020</td>\n    </tr>\n    <tr>\n      <td>11</td>\n      <td>December 1st, 2020</td>\n    </tr>\n    <tr>\n      <td>12</td>\n      <td>January 4th, 2021</td>\n    </tr>\n    <tr>\n      <td>13</td>\n      <td>February 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>14</td>\n      <td>March 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>15</td>\n      <td>April 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>16</td>\n      <td>May 3rd, 2021</td>\n    </tr>\n    <tr>\n      <td>17</td>\n      <td>June 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>18</td>\n      <td>July 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>19</td>\n      <td>August 2nd, 2021</td>\n    </tr>\n    <tr>\n      <td>20</td>\n      <td>September 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>21</td>\n      <td>October 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>22</td>\n      <td>November 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>23</td>\n      <td>December 1st, 2021</td>\n    </tr>\n    <tr>\n      <td>24</td>\n      <td>January 3rd, 2022</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 定期做XXX事情（分红、coupon、现金流...）的问题均可以通过以下Schedule的思路解决：\n",
    "\n",
    "beginning_date = ql.Date(1,1,2020)\n",
    "ending_date = ql.Date(1,1,2022)\n",
    "\n",
    "# 这里输入的是你预测、获取API、爬取数据（财务数据FCFF、FCFE、FC、分红、债券付息）的频次\n",
    "frequency = ql.Period(ql.Monthly)\n",
    "China_calendar_03 = ql.China()\n",
    "business_convention = ql.Following\n",
    "ending_business_convention = ql.Following\n",
    "date_generation = ql.DateGeneration.Forward\n",
    "end_of_month = False\n",
    "\n",
    "schedule = ql.Schedule(beginning_date,ending_date,frequency,China_calendar_03,business_convention,ending_business_convention,date_generation,end_of_month)\n",
    "\n",
    "pd.DataFrame({'乐学偶得-现金流发生日期':list(schedule)})"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PyCharm (sklearn)",
   "language": "python",
   "name": "pycharm-9607c1d0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}